from gibe.plugin import Plugin
from gibepages.model import Page

from turbogears import controllers, expose, identity, widgets, validators, error_handler, validate, paginate
import routes

from gibe.plugin import add_plugin_data
from gibe.util import utcnow, utc
from datetime import datetime, timedelta
from gibe import model

from tinymce import TinyMCE

try:
    from gibesitemap.plugin import Sitemap, SitemapUrl
except:
    Sitemap = None
    SitemapUrl = None

def add_utc_timezone(d):
    return d.replace(tzinfo=utc)


class PageFormFields(widgets.WidgetsList):
    id = widgets.HiddenField()
    title = widgets.TextField(validator=validators.NotEmpty())
    path = widgets.TextField()
    #content = widgets.TextArea(validator=validators.NotEmpty())
    content = TinyMCE(validator=validators.NotEmpty, label = "Content",
        mce_options = dict(
            mode = "exact",
            theme = "advanced",
            plugins = "fullscreen",
            relative_urls = False,
            theme_advanced_buttons2_add = "fullscreen",
            extended_valid_elements = "a[href|target|name]",
            paste_auto_cleanup_on_paste = True,
            paste_convert_headers_to_strong = True,
            paste_strip_class_attributes = "all",
            theme_advanced_buttons3 = "",
            remove_linebreaks = False,
            convert_newlines_to_brs = False,
            force_br_newlines = False,
        ),
        rows=25,
        cols=65,
    )
    content_format = widgets.HiddenField(default="html")
    
page_form = widgets.TableForm(fields=PageFormFields(), submit_text="Edit page")

class PageController(controllers.Controller):

    @expose()
    def import_(self, blog, action):
        import os.path

        from BeautifulSoup import BeautifulSoup

        def visitor(arg, dirname, fnames):
            if '.svn' in fnames:
                fnames.remove('.svn')
            for fname in fnames:
                try:
                    fullfname = os.path.join(dirname, fname)
                    if os.path.isfile(fullfname):
                        urlname = fullfname[len(arg['base']):]
                        if urlname[0] == "/":
                            urlname = urlname[1:]
                        if urlname.endswith('index.html'):
                            urlname = urlname[:-10]

                        bs = BeautifulSoup(open(fullfname).read())
                        title = bs.find('title').contents[0]

                        contents = bs.find(attrs=dict(id='resume'))
                        if not contents:
                            contents = bs.find(attrs={'class':'column-middle'})
                        contents = contents.prettify()
                        p = Page(title=title, content=contents, path = urlname, blog_id=1)
                except:
                    raise
            return

        base = '/home/user/mithrandr.moria.org'
        os.path.walk(base + '/resume', visitor, dict(base=base))
        return "Hello!!!"


    @expose(template="genshi:gibepages.templates.page")
    @add_plugin_data(template="genshi:gibepages.templates.page")
    def page(self, blog, action, page):
        return dict(page=page)

    @expose(template="genshi:gibepages.templates.page_editor")
    @identity.require(identity.in_group("admin"))
    @add_plugin_data()
    def page_editor(self, blog, action, id, **kw):
        d = {}
        d['page_form'] = page_form
        d['blog'] = blog
        if id:
            d['page'] = Page.get(id)
            d['page_values'] = vars(d['page'])
        else:
            d['page'] = None
            d['page_values'] = None
        return d

    @error_handler(page_editor)
    @validate(page_form)
    @add_plugin_data()
    def page_save(self, blog, action, id, **kw):
        if id:
            p = Page.get(id)
        else:
            p = Page()
        p.set(blog=blog, **kw)
        p.date_modified = datetime.now()
        p.save()
        raise routes.redirect_to('gibepages.page_list') 

    @expose(template="genshi:gibepages.templates.page_list")
    @add_plugin_data()
    @paginate('pages', limit = 20)
    def page_list(self, blog, **kw):
        d = {}
        d['pages'] = Page.select()
        return d


class GibePagesPlugin(Plugin):
    """
    This plugin adds a basic page management system to Gibe.
    """

    def initialise(self):
        if not Page.table.exists():
            Page.table.create()
        return True

    def contribute_sitemaps(self, blog, sitemaps, context):
        sitemaps.append(Sitemap("gibepages_pages"))

    def contribute_sitemap(self, blog, sitemap_name, sitemap_entries, context):
        sitemap_name = sitemap_name.replace('.', '_')
        contribute_specific_sitemap = getattr(self, '_contribute_sitemap_%s' % (sitemap_name,), None)
        if contribute_specific_sitemap:
            contribute_specific_sitemap(blog, sitemap_entries, context)

    def _contribute_sitemap_gibepages_pages(self, blog, sitemap_entries, context):
        page_count = 0
        now = utcnow()
        for page in Page.select(order_by=model.desc(Page.c.date_modified)):
            modification_time = add_utc_timezone(page.date_modified)

            if modification_time + timedelta(days=3) > now:
                changefreq = "hourly"
            elif modification_time + timedelta(days=15) > now:
                changefreq = "daily"
            elif modification_time + timedelta(days=45) > now:
                changefreq = "weekly"
            elif modification_time + timedelta(days=90) > now:
                changefreq = "monthly"
            else:
                changefreq = "monthly"

            path_parts = len([k for k in page.path.split('/') if k])
            if path_parts == 1:
                priority = 0.9
            elif path_parts == 2:
                priority = 0.8
            elif path_parts == 3:
                priority = 0.7
            else:
                priority = 0.6

            sitemap_entries.append(SitemapUrl(routes.url_for('gibepages.page', path=page.path, qualified=True), lastmod = modification_time, changefreq = changefreq, priority=priority))

    def map_routes(self, blog, maps, controllers):
        """
        General plan:

        1. Find the current "posts" route.
        2. Copy it
        3. Replace the URL portion with just the :slug
        4. Replace the post_expand filter so that URLs don't have excess
           arguments (year, month...)
        5. Add a condition function that makes this route conditional of the
           slug existing in the Post table.
        6. Insert the route before the existing "posts" route.
        """

        controllers['gibepages.PageController'] = PageController()
        def page_expand(kargs):
            if 'page' not in kargs:
                return kargs

            page = kargs.pop('page')
            kargs['path'] = page.path

            return kargs

        def pageid_expand(kargs):
            if 'page' not in kargs:
                return kargs

            page = kargs.pop('page')
            if not page:
                return kargs

            kargs['id'] = page.page_id
            return kargs


        # add condition function
        def page_condition(environ, match_dict):
            path = match_dict.pop('path')
            import cherrypy
            if cherrypy.request.path[-1:] == "/":
                path = path + "/"
            page = Page.get_by(path=path)
            if not page:
                if path[-1:] != "/":
                    if Page.get_by(path=path + "/"):
                        raise routes.redirect_to('gibepages.page', path=path + "/")
                page = Page.get_by(path=path)
                return False
            
            match_dict['page'] = page

            return True

        maps.append(('gibepages.page', '*path', dict(controller='gibepages.PageController', action='page', conditions=dict(function=page_condition))))
        maps.append(('gibepages.page_list', 'admin/pages', dict(controller='gibepages.PageController', action='page_list')))
        maps.append(('gibepages.page_editor', 'admin/pages/edit/:id', dict(controller='gibepages.PageController', action='page_editor', _filter=pageid_expand, _method="GET")))
        maps.append(('gibepages.page_save', 'admin/pages/edit/:id', dict(controller='gibepages.PageController', action='page_save', _filter=pageid_expand, _method="POST")))
        maps.append(('gibepages.import', 'import', dict(controller='gibepages.PageController', action='import_')))

        return

